package com.geek.config.microprofile;

import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.spi.ConfigBuilder;
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class DefaultConfigProviderResolver extends ConfigProviderResolver {

  ConcurrentHashMap<ClassLoader, Config> classLoaderConfig = new ConcurrentHashMap<>();


  @Override
  public Config getConfig() {
    return getConfig(null);
  }

  @Override
  public Config getConfig(ClassLoader classLoader) {
    classLoader = Optional.ofNullable(classLoader).orElse(getClass().getClassLoader());
    return classLoaderConfig.computeIfAbsent(classLoader, classLoader1 -> newConfig(classLoader1));
  }

  protected Config newConfig(ClassLoader classLoader) {
    return newConfigBuilder(classLoader).build();
  }

  protected ConfigBuilder newConfigBuilder(ClassLoader classLoader) {
    return new DefaultConfigBuilder(classLoader);
  }

  @Override
  public ConfigBuilder getBuilder() {
    return newConfigBuilder(getClass().getClassLoader());
  }

  @Override
  public void registerConfig(Config config, ClassLoader classLoader) {
    classLoaderConfig.put(classLoader, config);
  }

  @Override
  public void releaseConfig(Config config) {
    List<ClassLoader> collect = classLoaderConfig.entrySet()
            .stream()
            .filter(entry -> entry.getValue().equals(config))
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());
    collect.forEach(classLoaderConfig::remove);
  }
}
